package com.dubious.interview.euler.prime;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class DumpPrimesToFile {

    public static void main(String[] args) throws Exception
    {
        String filePath = "primes.txt";
        long upperBound = 10000000000L;
        
        long lastPrime = 0;
        
        // We write into the file the gaps between each prime.
        // The format of the file is as follows:
        // If the gap can be written in a byte, then write it as so.
        // If the gap must be written larger than a byte, then prefix with a 0-value byte followed by the entire long.
        
        // At least in the range up to 10,000,000,000 the gap is very rarely larger than a byte.
        
        try
        {
            DataOutputStream writer =
                    new DataOutputStream(
                    new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(filePath))));
            for(Long prime : new SievePrimeIterator(upperBound))
            {
                long difference = prime - lastPrime;
                if(difference >> 8 == 0)
                {
                    // information can be stored in a single bit, so do it
                    writer.write((byte)difference);
                } else
                {
                    // the difference has to be stored in multiple bytes.  we will just simply store it as a complete long.
                    // to denote this we prepend with a 0-value byte
                    writer.write(0);
                    writer.writeLong(difference);
                }
                lastPrime = prime;
            }
            writer.write(0);
            writer.close();
        } catch (Error e)
        {
            // Wrap in some error-handling code for dealing with Out-Of-Memory errors.
            System.out.println("Last prime written: " + lastPrime);
            throw e;
        }
        
        /*
        // let's read the file to ensure it is ok
        BufferedInputStream reader = new BufferedInputStream(new FileInputStream(filePath));
        int nextByte = reader.read();
        int nextPrime = 0;
        do
        {
            nextPrime += nextByte;
            System.out.println("Number: " + nextPrime);
            nextByte = reader.read();
        } while(nextByte > 0);
        reader.close();
        */
    }
}
